#include "version.h"
#include "config.h"
#include <cjson/cJSON.h>
#include <dirent.h>
#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

// 名称排序
int compare_strings(const void *a, const void *b) {
  return strcmp(*(const char **)a, *(const char **)b);
}

// 初始化版本数据
void init_versions(VersionState *state, ConfigState *ConfigState) {
  // 排序方式: 0名称  1时间
  // int order = 0;
  state->version_count = 0;
  state->selected_version = 0;
  state->scroll_offset = 0;
  char *gameDir = ConfigState->items[2].value;
  char versionDir[256];
  snprintf(versionDir, sizeof(versionDir), "%s/versions/", gameDir);
  DIR *dirp = opendir(versionDir);
  struct dirent *entry;

  // 简单的名称收集和排序
  state->versions = malloc(100 * sizeof(*(state->versions)));
  int count = 0;

  while ((entry = readdir(dirp)) != NULL && count < 100) {
    // 跳过 "." 和 ".."
    if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 &&
        entry->d_type == DT_DIR) {
      char versionPath[200];
      strcpy(versionPath, versionDir);
      strcat(versionPath, entry->d_name);
      strcat(versionPath, "/");
      DIR *child_dirp = opendir(versionPath);
      struct dirent *child_entry;
      char jsonName[100];
      strcpy(jsonName, entry->d_name);
      strcat(jsonName, ".json");
      char jarName[100];
      strcpy(jarName, entry->d_name);
      strcat(jarName, ".jar");
      int haveJar = 0;
      int haveJson = 0;
      while ((child_entry = readdir(child_dirp)) != NULL) {
        // Is it have jar file
        if (strcmp(child_entry->d_name, jarName) == 0) {
          haveJar = 1;
        }
        // Is it have json file
        if (strcmp(child_entry->d_name, jsonName) == 0) {
          haveJson = 1;
        }
      }
      if (haveJar == 1 && haveJson == 1) {
        // open and prase Json
        char json_path[200];
        strcpy(json_path, versionPath);
        strcat(json_path, jsonName);

        FILE *json_file = fopen(json_path, "r");

        if (json_file != NULL) {
          // get the size of json file
          fseek(json_file, 0, SEEK_END);
          long json_file_size = ftell(json_file);
          fseek(json_file, 0, SEEK_SET);

          // 读取文件内容
          char *json_data = malloc(json_file_size + 1);
          fread(json_data, 1, json_file_size, json_file);
          json_data[json_file_size] = '\0';
          fclose(json_file);

          // 解析 JSON
          cJSON *json = cJSON_Parse(json_data);
          free(json_data);

          if (json != NULL) {
            cJSON *game_version = cJSON_GetObjectItem(json, "gameVersion");
            cJSON *game_type = cJSON_GetObjectItem(json, "type");
            // if (game_version != NULL && game_type != NULL) {
            if (game_type != NULL) {
              strcpy(state->versions[count].type, game_type->valuestring);
              strcpy(state->versions[count].name, entry->d_name);
              if (game_version == NULL) {
                strcpy(state->versions[count].version, "unkonwn");
              } else {
                strcpy(state->versions[count].version,
                       game_version->valuestring);
              }
              strcpy(state->versions[count].modloader, "");
              count++;
            }
          }
        }
      }
    }
  }
  closedir(dirp);

  // Rank in name
  for (int i = 0; i < count - 1; i++) {
    for (int j = i + 1; j < count; j++) {
      if (strcmp(state->versions[i].name, state->versions[j].name) > 0) {
        VersionInfo temp = state->versions[i];
        state->versions[i] = state->versions[j];
        state->versions[j] = temp;
      }
    }
  }

  state->version_count = count;
}

// 启动版本函数
void begin_version(VersionState *state, ConfigState *ConfigState) {
  endwin();
  // 这里可以添加实际启动游戏的代码
  // 例如：构建启动命令并执行// 启动Minecraft游戏
  int index = state->selected_version;
  char *minecraft_dir = ConfigState->items[2].value;
  char version_dir[256];
  snprintf(version_dir, sizeof(version_dir), "%s/versions/%s", minecraft_dir,
           state->versions[index].name);
  char *java_path = ConfigState->items[0].value;

  // 构建classpath
  char classpath[10240] = ""; // 足够大的缓冲区

  // 添加库文件到classpath
  char find_command[1024];
  snprintf(find_command, sizeof(find_command),
           "find %s/libraries -name \"*.jar\" | tr '\\n' ':'", minecraft_dir);

  FILE *fp = popen(find_command, "r");
  if (fp == NULL) {
    perror("popen failed");
  }

  fgets(classpath, sizeof(classpath) - 1, fp);
  pclose(fp);

  // 移除末尾的换行符和冒号
  size_t len = strlen(classpath);
  if (len > 0 && classpath[len - 1] == '\n') {
    classpath[len - 1] = '\0';
  }
  if (len > 0 && classpath[len - 1] == ':') {
    classpath[len - 1] = '\0';
  }

  // 添加主游戏jar文件
  strcat(classpath, ":");
  strcat(classpath, version_dir);
  strcat(classpath, "/");
  strcat(classpath, state->versions[index].name);
  strcat(classpath, ".jar");

  // 准备参数
  char *args[100];
  int arg_count = 0;

  char max_memory[64];
  char max_memory_arg[70];
  strcpy(max_memory, ConfigState->items[1].value);
  snprintf(max_memory_arg, sizeof(max_memory_arg), "-Xmx%sm", max_memory);

  char assets_path[164];
  snprintf(assets_path, sizeof(assets_path), "%s/assets", minecraft_dir);

  args[arg_count++] = java_path;
  args[arg_count++] = max_memory_arg;
  args[arg_count++] = "-Djava.library.path=/home/xy/.minecraft/versions/"
                      "1.21.10/natives-linux-x86_64";
  args[arg_count++] = "-cp";
  args[arg_count++] = classpath;
  args[arg_count++] = "net.minecraft.client.main.Main";
  args[arg_count++] = "--username";
  args[arg_count++] = "rectifier";
  args[arg_count++] = "--version";
  args[arg_count++] = "1.21.10";
  args[arg_count++] = "--gameDir";
  args[arg_count++] = minecraft_dir;
  args[arg_count++] = "--assetsDir";
  args[arg_count++] = assets_path;
  args[arg_count++] = "--assetIndex";
  args[arg_count++] = "27";
  args[arg_count++] = "--accessToken";
  args[arg_count++] = "offline_token";
  args[arg_count++] = "--uuid";
  args[arg_count++] = "00000000-0000-0000-0000-000000000000";
  args[arg_count++] = "--userType";
  args[arg_count++] = "mojang";
  args[arg_count] = NULL; // 参数列表必须以NULL结尾

  // 切换到Minecraft目录
  if (chdir(minecraft_dir) != 0) {
    perror("chdir failed");
  }

  // 创建子进程执行游戏
  pid_t pid = fork();
  if (pid == 0) {
    // 子进程
    execvp(java_path, args);
    // 如果execvp返回，说明出错了
    perror("execvp failed");
    exit(1);
  } else if (pid > 0) {
    // 父进程
    printf("Minecraft启动中 (PID: %d)...\n", pid);

    int status;
    waitpid(pid, &status, 0);

    if (WIFEXITED(status)) {
      printf("Minecraft已退出，退出码: %d\n", WEXITSTATUS(status));
    } else if (WIFSIGNALED(status)) {
      printf("Minecraft被信号终止: %d\n", WTERMSIG(status));
    }

  } else {
    perror("fork failed");
  }
}

// mod函数
void mod(VersionState *state, int index) {
  if (index < 0 || index >= state->version_count)
    return;
}
// 重命名版本函数
void rename_version(VersionState *state, int index) {
  if (index < 0 || index >= state->version_count)
    return;

  int row, col;
  getmaxyx(stdscr, row, col);

  echo(); // 开启回显
  curs_set(1);
  clear();

  mvprintw(3, 2, "Rename version: %s", state->versions[index].version);
  mvprintw(5, 2, "Current name: %s", state->versions[index].name);
  mvprintw(7, 2, "Enter new name: ");

  char new_name[64];
  getnstr(new_name, sizeof(new_name) - 1);

  strncpy(state->versions[index].name, new_name,
          sizeof(state->versions[index].name) - 1);

  noecho(); // 关闭回显
  curs_set(0);

  // 清除重命名界面，主循环会重新绘制完整界面
  clear();
}

// 新建版本函数
void new_version(VersionState *state) {
  // 这里可以添加新建版本的逻辑
  // 例如：弹出对话框让用户输入版本信息
}

// 删除版本函数
void delete_version(VersionState *state, int index, ConfigState *ConfigState) {
  if (index < 0 || index >= state->version_count) {
    return;
  }

  echo();      // 开启回显
  curs_set(1); // 显示光标
  clear();

  mvprintw(3, 2, "delete version: %s", state->versions[index].name);
  mvprintw(5, 2, "Do you want to delete[y/N]");
  char c = getch();
  char delete_command[1020];
  switch (c) {
  case 'y':
    snprintf(delete_command, sizeof(delete_command), "rm -rf %s/versions/%s",
             ConfigState->items[2].value, state->versions[index].name);
    system(delete_command);
    break;
  default:
    break;
  }
  noecho(); // 关闭回显
  curs_set(0);

  init_versions(state, ConfigState);

  // 清除重命名界面，主循环会重新绘制完整界面
  clear();
  return;
}

// 版本页面主函数
void version_page(int ch, int *middlep, VersionState *state,
                  ConfigState *ConfigState) {
  clear();
  int row = 0, col = 0;
  getmaxyx(stdscr, row, col);

  // 处理版本选择导航
  switch (ch) {
  case 'j': // 向下选择版本
    if (state->selected_version < state->version_count - 1) {
      state->selected_version++;
      int visible_rows = row - 10;
      if (state->selected_version >= state->scroll_offset + visible_rows) {
        state->scroll_offset++;
      }
    }
    break;
  case 'k': // 向上选择版本
    if (state->selected_version > 0) {
      state->selected_version--;
      if (state->selected_version < state->scroll_offset) {
        state->scroll_offset--;
      }
    }
    break;
  case 'b': // begin 操作 - 直接执行
    begin_version(state, ConfigState);
    *middlep = 0; // 移动光标到 start
    break;
  case 'm':
    *middlep = 1;
    mod(state, state->selected_version);
    break;
  case 'r': // rename 操作 - 直接执行
    rename_version(state, state->selected_version);
    *middlep = 2; // 移动光标到 rename
    break;
  case 'n': // new 操作 - 直接执行
    new_version(state);
    *middlep = 3; // 移动光标到 new
    break;
  case 'd': // delete 操作 - 直接执行
    delete_version(state, state->selected_version, ConfigState);
    *middlep = 4; // 移动光标到 delete
    break;
  case 'h':                        // 在操作间向左移动
    *middlep = (*middlep + 4) % 5; // 循环向左（5个操作）
    break;
  case 'l':                        // 在操作间向右移动
    *middlep = (*middlep + 1) % 5; // 循环向右（5个操作）
    break;
  case '\n': // 回车键执行当前操作
    switch (*middlep) {
    case 0: // begin
      begin_version(state, ConfigState);
      break;
    case 1: // mod
      mod(state, state->selected_version);
      break;
    case 2: // rename
      rename_version(state, state->selected_version);
      break;
    case 3: // new
      new_version(state);
      break;
    case 4: // delete
      delete_version(state, state->selected_version, ConfigState);
      break;
    }
    break;
  }

  // 显示版本列表标题
  mvprintw(2, 2, "Type    Modloader Version   Name");
  mvprintw(3, 2, "----    --------- -------   ----");

  // 显示版本列表
  int start_y = 4;                     // 列表开始的行
  int max_display = row - start_y - 4; // 最大显示数量

  for (int i = state->scroll_offset;
       i < state->version_count && i < state->scroll_offset + max_display;
       i++) {

    // 移动到正确的位置
    move(start_y + i - state->scroll_offset, 2);

    // 如果是选中的版本，高亮显示
    if (i == state->selected_version) {
      attron(A_REVERSE);
    }

    // 如果是选定版本，标记星号
    // char chosen_mark = (i == state->chosen_version) ? '*' : ' ';

    // 显示版本信息：类型、模组加载器、版本号、名字
    printw("%-7s %-9s %-9s %s", state->versions[i].type,
           state->versions[i].modloader, state->versions[i].version,
           state->versions[i].name);

    if (i == state->selected_version) {
      attroff(A_REVERSE);
    }
  }

  // 显示滚动提示
  if (state->scroll_offset > 0) {
    mvprintw(start_y - 1, 2, "...more above...");
  }
  if (state->scroll_offset + max_display < state->version_count) {
    mvprintw(start_y + max_display, 2, "...more below...");
  }

  // 底部操作提示
  switch (*middlep) {
  case 0:
    attron(A_REVERSE);
    mvprintw(row - 1, 0, "[b]egin");
    attroff(A_REVERSE);
    printw(" [m]od [r]ename [n]ew [d]elete");
    break;
  case 1:
    mvprintw(row - 1, 0, "[b]egin ");
    attron(A_REVERSE);
    printw("[m]od");
    attroff(A_REVERSE);
    printw(" [r]ename [n]ew [d]elete");
    break;
  case 2:
    mvprintw(row - 1, 0, "[b]egin [m]od ");
    attron(A_REVERSE);
    printw("[r]ename");
    attroff(A_REVERSE);
    printw(" [n]ew [d]elete");
    break;
  case 3:
    mvprintw(row - 1, 0, "[b]egin [m]od [r]ename ");
    attron(A_REVERSE);
    printw("[n]ew");
    attroff(A_REVERSE);
    printw(" [d]elete");
    break;
  case 4:
    mvprintw(row - 1, 0, "[b]egin [m]od [r]ename [n]ew ");
    attron(A_REVERSE);
    printw("[d]elete");
    attroff(A_REVERSE);
    break;
  }

  // 页面标题和导航
  move(0, 0);
  attron(A_REVERSE);
  printw("[V]ersion");
  attroff(A_REVERSE);
  printw(" [C]onfig [A]ccount");
  mvprintw(0, col - 15, "tap [q] to quit");
}

// 清理版本数据
void free_versions(VersionState *state) {
  if (state->versions) {
    free(state->versions);
    state->versions = NULL;
  }
  state->version_count = 0;
}
